/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.opgea.token.dao.impl;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.opgea.token.dao.TokenDAO;
import com.opgea.token.domain.entities.Destination;
import com.opgea.token.domain.entities.Token;
import com.opgea.token.domain.qualifiers.TokenStatusQualifier;

/**
 * 
 * @author Ramesh
 */
@Repository
public class TokenDAOImpl implements TokenDAO {

    @Autowired
    private SessionFactory sessionFactory;

    @Override
    public Integer getMaxTokenNumber(Long companyId, String dateString) {
	Session session = sessionFactory.openSession();
	Query query = session.createQuery("SELECT max(t.tokenNo) FROM Token t "
		+ " WHERE t.company.id = " + companyId + " AND "
		+ " t.tokenDate = '" + dateString + "' ");
	System.out.println("TokenContextLoaderListener: "
		+ query.getQueryString());
	return (Integer) query.uniqueResult();
    }

    @Override
    public Token create(Token token) {
	sessionFactory.getCurrentSession().save(token);
	return token;
    }

    @Override
    public Token update(Token token) {
	throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public Token find(Long id) {
	Query query = sessionFactory.getCurrentSession()
		.getNamedQuery("Token.findById").setParameter("id", id);
	Token token = (Token) query.uniqueResult();
	return token;
    }

    @Override
    public Token findByTokenNo(Long companyId, Integer tokenNo, Date date) {

	SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
	String dateString = dateFormat.format(date);
	String sqlQuery = "SELECT t FROM Token t WHERE t.tokenNo = " + tokenNo
		+ " AND " + " t.tokenDate = '" + dateString + "' AND "
		+ " t.company.id = '" + companyId + "' ";
	Query query = sessionFactory.getCurrentSession().createQuery(sqlQuery);
	Token token = (Token) query.uniqueResult();
	return token;
    }

    @Override
    public Token findAll() {
	throw new UnsupportedOperationException("Not supported yet.");
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<Token> findAll(Long companyId, Date date) {
	Query query = sessionFactory.getCurrentSession()
		.getNamedQuery("Token.findAllByCompanyId")
		.setParameter("companyId", companyId)
		.setParameter("tokenDate", date);
	List<Token> tokenList = query.list();
	return tokenList;
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<Token> findAllByStatus(Long companyId, Date date,
	    TokenStatusQualifier qualifier) {
	Query query = sessionFactory.getCurrentSession()
		.getNamedQuery("Token.findAllByCompanyIdAndStatus")
		.setParameter("companyId", companyId)
		.setParameter("tokenDate", date)
		.setParameter("tokenStatus", qualifier);
	List<Token> tokenList = query.list();
	return tokenList;
    }

    @SuppressWarnings("unchecked")
    @Override
    public List<Token> findTokensInQueue(Long companyId, Integer tokenNo) {
	Date date = Calendar.getInstance().getTime();
	SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
	String dateString = dateFormat.format(date);

	// Token token = this.find(new Long(tokenNo));
	Token token = this.findByTokenNo(companyId, tokenNo, date);
	Destination destination = null;
	if (token != null) {
	    destination = token.getTokenDetails().getDestination();
	}

	StringBuilder sql = new StringBuilder();
	sql.append(" SELECT t FROM Token t WHERE ");
	sql.append(" t.tokenNo <= ");
	sql.append(tokenNo);
	sql.append(" AND t.tokenDate = ");
	sql.append(" '");
	sql.append(dateString);
	sql.append("' ");
	sql.append(" AND t.company.id = ");
	sql.append(companyId);
	sql.append(" AND t.tokenDetails.destination.id = ");
	if (destination != null) {
	    sql.append(destination.getId());
	} else {
	    sql.append(" 0");
	}
	sql.append(" AND t.tokenDetails.tokenStatus = ");
	sql.append(TokenStatusQualifier.NEW.ordinal());

	Query query = sessionFactory.getCurrentSession().createQuery(
		sql.toString());
	List<Token> tokenList = query.list();
	return tokenList;
    }

}
